import { PackageManagerTabs } from '@theme';
import { Stability } from '@components/ApiMeta.tsx';

# React

## 如何使用

Rspack 提供两种方案来支持 React：

- **使用 Rsbuild**：Rsbuild 提供对 React 开箱即用的支持，能够快速创建一个 React 项目，详见 [Rsbuild - React](https://rsbuild.rs/zh/guide/framework/react)。
- **手动配置 Rspack**：你可以参考当前文档，手动添加 React 相关的配置。

## 配置 JSX/TSX

Rspack 使用 SWC 转译器支持 JSX 和 TSX。

你可以添加 [builtin:swc-loader](/guide/features/builtin-swc-loader) 以支持 `.jsx` 和 `.tsx` 文件：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.jsx$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            jsc: {
              parser: {
                syntax: 'ecmascript',
                jsx: true,
              },
            },
          },
        },
        type: 'javascript/auto',
      },
      {
        test: /\.tsx$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            jsc: {
              parser: {
                syntax: 'typescript',
                tsx: true,
              },
            },
          },
        },
        type: 'javascript/auto',
      },
    ],
  },
};
```

关于配置项的更多信息请参考 [builtin:swc-loader](/guide/features/builtin-swc-loader)。

## Fast Refresh

通过 [@rspack/plugin-react-refresh](https://www.npmjs.com/package/@rspack/plugin-react-refresh) 支持 React Fast Refresh 功能，首先需要安装相关依赖：

<PackageManagerTabs command="add @rspack/plugin-react-refresh react-refresh -D" />

[React Fast Refresh](https://reactnative.dev/docs/fast-refresh) 功能的开启主要分为两部分：代码注入和代码转换：

- 代码注入会注入 `react-refresh` 包中的一些代码，以及一些自定义的运行时代码，都已集成在 [@rspack/plugin-react-refresh](https://github.com/rspack-contrib/rspack-plugin-react-refresh) 插件中，可通过该插件注入。
- 代码转换可通过 loader 来完成，比如 `swc-loader` 的 [jsc.transform.react.refresh](https://swc.rs/docs/configuration/compilation#jsctransformreactrefresh) 或 `babel-loader` 的 [react-refresh/babel 插件](https://github.com/facebook/react/tree/main/packages/react-refresh)。

```js title="rspack.config.mjs"
import { rspack } from '@rspack/core';
import ReactRefreshPlugin from '@rspack/plugin-react-refresh';

const isDev = process.env.NODE_ENV === 'development';

export default {
  // ...
  mode: isDev ? 'development' : 'production',
  module: {
    rules: [
      {
        test: /\.jsx$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            jsc: {
              parser: {
                syntax: 'ecmascript',
                jsx: true,
              },
              transform: {
                react: {
                  development: isDev,
                  refresh: isDev,
                },
              },
            },
          },
        },
      },
    ],
  },
  plugins: [
    isDev && new ReactRefreshPlugin(),
    isDev && new rspack.HotModuleReplacementPlugin(),
  ],
};
```

这种实现方式将代码注入逻辑和转换逻辑解耦，代码注入逻辑统一通过 `@rspack/plugin-react-refresh` 插件完成，代码转换通过 loader 完成。这意味着该插件可以配合 `builtin:swc-loader`、`swc-loader` 或 `babel-loader` 使用：

- 配合 `builtin:swc-loader` 使用方式可参考：[examples/react-refresh](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/react-refresh)，使用 `swc-loader` 只需将 `builtin:swc-loader` 换为 `swc-loader` 即可。
- 配合 `babel-loader` 的使用方式可参考：[examples/react-refresh-babel-loader](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/react-refresh-babel-loader)

## React Compiler

React Compiler 是 React 19 引入的一个实验性编译器，它可以自动优化你的 React 代码。

在开始使用 React Compiler 之前，建议阅读 [React Compiler 文档](https://zh-hans.react.dev/learn/react-compiler)，以了解 React Compiler 的功能、当前状态和使用方法。

:::tip
React Compiler 目前仅支持 Babel 编译，这会导致构建时间变慢。
:::

### 如何使用

在 Rspack 中使用 React Compiler 的步骤如下：

1. 升级 `react` 和 `react-dom` 版本到 19。如果你暂时无法升级，可以在 React 17 或 18 项目中安装 [react-compiler-runtime](https://www.npmjs.com/package/react-compiler-runtime)，以允许编译后的代码在 19 之前的版本上运行。
2. 目前 React Compiler 仅提供了 Babel 插件，你需要安装：

- [@babel/core](https://www.npmjs.com/package/@babel/core)
- [babel-loader](https://www.npmjs.com/package/babel-loader)
- [babel-plugin-react-compiler](https://www.npmjs.com/package/babel-plugin-react-compiler)
- [@babel/plugin-syntax-jsx](https://www.npmjs.com/package/@babel/plugin-syntax-jsx)

3. 在你的 Rspack 配置中注册 `babel-loader`：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'builtin:swc-loader',
            options: {
              // SWC options for JS
            },
          },
        ],
      },
      {
        test: /\.jsx$/,
        use: [
          {
            loader: 'builtin:swc-loader',
            options: {
              // SWC options for JSX
            },
          },
          { loader: 'babel-loader' },
        ],
      },
    ],
  },
};
```

4. 创建 `babel.config.js` 并配置插件：

```js title="babel.config.js"
const ReactCompilerConfig = {
  /* ... */
};

module.exports = function () {
  return {
    plugins: [
      ['babel-plugin-react-compiler', ReactCompilerConfig], // must run first!
      '@babel/plugin-syntax-jsx',
    ],
  };
};
```

对于 React 17 和 18 的项目，除了安装 [react-compiler-runtime](https://www.npmjs.com/package/react-compiler-runtime)，还需要指定 `target`：

```js title="babel.config.js"
const ReactCompilerConfig = {
  target: '18', // '17' | '18' | '19'
};
```

### 示例

你可以参考以下示例项目：

- [Rspack + React Compiler](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/react-compiler-babel)
- [Rspack + React Compiler + TypeScript](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/react-compiler-babel-ts)

## 集成 SVGR

[SVGR](https://react-svgr.com/) 是一个用于将 SVG 转换为 React 组件的工具，

在 Rspack 中使用 SVGR 的方式与 webpack 中完全一致：

```js title="rspack.config.mjs"
export default {
  module: {
    rules: [
      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        use: ['@svgr/webpack'],
      },
    ],
  },
};
```

对于 SVGR 的详细用法，请参考 [SVGR 文档 - webpack](https://react-svgr.com/docs/webpack/)。
